package com.ruoyi.manage.service.impl;

import com.github.wxpay.sdk.WXPayUtil;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.manage.mapper.OrderInfoMapper;
import com.ruoyi.manage.service.IWxChatPayService;
import com.ruoyi.manage.utils.QrCodeBase64;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * @author : 赵志冲
 * @date : 2024-07-02 22:02
 * @description :
 **/
@Service
public class WxChatPayServiceImpl implements IWxChatPayService {

    @Autowired
    OrderInfoMapper orderInfoMapper;

    @Value("${weixin.appId}")
    String appId;

    @Value("${weixin.mchId}")
    String mchId;

    @Value("${weixin.partnerKey}")
    String partnerKey;

    @Value("${weixin.notifyurl}")
    String notifyUrl;
    @Override
    public R<Map<String, Object>> wxChatPay(String orderId, Integer amount) {
        try {
            // 创建OkHttpClient实例用于发送网络请求
            OkHttpClient okHttpClient = new OkHttpClient();
            // 准备微信支付请求参数
            Map<String,String> map = new HashMap<>(16);
            // 设置微信支付相关的app ID和商户号
            map.put("appid",appId);
            map.put("mch_id",mchId);
            //防止重复攻击
            map.put("nonce_str", WXPayUtil.generateNonceStr());
            // 设置订单描述、订单号、订单金额等信息
            map.put("body","测试商品");
            map.put("out_trade_no",orderId);
            //订单金额，单位为分
            map.put("total_fee","1");
            //发起支付的机器IP
            map.put("spbill_create_ip","127.0.0.1");
            //支付结果通知
            map.put("notify_url",notifyUrl);
            //扫码支付
            map.put("trade_type","NATIVE");
            map.put("sign",WXPayUtil.generateSignature(map,partnerKey));
            //Map 转换为xml
            String body = WXPayUtil.mapToXml(map);

            System.out.println(body);

            System.out.println("----------------");
            // 发起支付请求
            RequestBody requestBody = RequestBody.create(body,
                    MediaType.parse("application/xml; charset=utf-8"));

            Request request = new Request.Builder()
                    .url("https://api.mch.weixin.qq.com/pay/unifiedorder")
                    .post(requestBody)
                    .build();
            Response response = okHttpClient.newCall(request).execute();
            // 处理支付请求的响应
            assert response.body() != null;
            String responseBody = response.body().string();

            System.out.println(responseBody);
            // 根据响应生成支付二维码
            Map<String, String> responseMap = WXPayUtil.xmlToMap(responseBody);

            Map<String,Object> mapReturn = new HashMap<>(16);

            String returnCode = responseMap.get("return_code");

            String returnMsg = responseMap.get("return_msg");

            String success = "SUCCESS";
            if (success.equalsIgnoreCase(returnCode)){
                String codeUrl = responseMap.get("code_url");
                System.out.println(codeUrl);
                // 生成二维码的Base64编码
                mapReturn.put("qrcode", QrCodeBase64.genQrCodeAsBase64(codeUrl));
            }else {
                // 输出错误信息
                System.out.println("错误信息,"+ returnMsg);
            }
            // 返回包含支付二维码信息的结果
            return R.ok(mapReturn);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public R<String> queryWxOrder(Long orderId) {
        try {
            // 创建OkHttpClient实例
            OkHttpClient okHttpClient = new OkHttpClient();
            // 初始化请求参数
            Map<String,String> map = new HashMap<>(16);
            map.put("appid",appId);
            map.put("mch_id",mchId);
            //防止重放攻击
            map.put("nonce_str", WXPayUtil.generateNonceStr());
            //商户系统内唯一
            map.put("out_trade_no", String.valueOf(orderId));
            map.put("sign",WXPayUtil.generateSignature(map,partnerKey));

            //Map 转为XML
            String body = WXPayUtil.mapToXml(map);
            // 创建RequestBody，设置请求体
            RequestBody requestBody = RequestBody.create(body,
                    MediaType.parse("application/xml; charset=utf-8")
            );//请求体
            // 构建请求
            Request request = new Request.Builder()
                    .url("https://api.mch.weixin.qq.com/pay/orderquery")
                    .post(requestBody)
                    .build();//请求

            // 发送请求并获取响应
            Response response = okHttpClient.newCall(request).execute();
            // 检查响应体不为空并转换为字符串
            assert response.body() != null;
            String responseBodyString = response.body().string();
            System.out.println(responseBodyString);
            // 将XML响应转换为Map
            Map<String, String> responseMap = WXPayUtil.xmlToMap(responseBodyString);
            String code = "";
            String returnCode = responseMap.get("return_code");
            String returnMsg = responseMap.get("return_msg");
            String success = "SUCCESS";
            // 判断返回码是否成功
            if (returnCode.equalsIgnoreCase(success)){
                String resultCode = responseMap.get("result_code");
                String tradeState = responseMap.get("trade_state");
                //根据交易状态返回业务结果
                if (resultCode.equalsIgnoreCase(success)){
                    System.out.println("trade_state");
                    //记录交易状态
                    code = tradeState;

                }else {
                    System.out.println("错误信息,"+returnMsg);
                }
            }else{
                System.out.println("错误信息,"+returnMsg);
            }
            // 根据交易状态返回业务结果
            String notPay = "NOTPAY";
            String userPaying = "USERPAYING";
            if (success.equals(code)){
                orderInfoMapper.updateOrderInfo(orderId);
                return R.ok("已支付");
            }
            if (notPay.equals(code)){
                return R.ok("未支付");
            }
            if (userPaying.equals(code)){
                return R.ok("用户支付中");
            }
            //返回其他状态码
            return R.ok(code);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
